package com.ccx.demo.business.user.vo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import com.ccx.demo.business.user.entity.QTabUser;
import com.ccx.demo.business.user.entity.TabUser;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.ToString;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.BeanUtils;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static io.swagger.annotations.ApiModelProperty.AccessMode.READ_ONLY;

/**
 * 用户实体
 *
 * @author 谢长春
 */
@ApiModel(description = "扩展用户实体VO")
@Getter
@Setter
@ToString(callSuper = true)
@JSONType(
        ignores = {"password"}, // 序列化时忽略属性，反序列化不受影响
        orders = {"id", "domain", "username", "nickname", "phone", "email", "role", "registerSource", "deleted"}
)
public class TabUserVO extends TabUser {

    private static final long serialVersionUID = 7185030320855492326L;

    @SneakyThrows
    public static TabUserVO ofTabUser(final TabUser entity) {
        return Optional.ofNullable(entity).map(obj -> {
            final TabUserVO vo = new TabUserVO();
            BeanUtils.copyProperties(entity, vo);
            return vo;
        }).orElseGet(TabUserVO::new);
    }

    /**
     * 权限指令集合
     */
    @ApiModelProperty(value = "权限指令代码集合", accessMode = READ_ONLY, position = 21)
    private List<String> authorityList;

    /**
     * 模糊匹配：用户名/昵称/手机号/邮箱
     */
    @ApiModelProperty(value = "模糊匹配：用户名/昵称/手机号/邮箱", position = 22)
    private String containsAll;

    @JSONField(deserialize = false)
    public List<String> getAuthorityList() {
        if (ArrayUtils.isEmpty(getRoles())) {
            return Collections.emptyList();
        }
        if (CollectionUtils.isEmpty(authorityList)) {
            authorityList = Stream.of(getRoles())
                    .distinct()
                    .flatMap(id -> Stream.of(getRoleAuthoritiesCacheById(id)))
                    .collect(Collectors.toList());
        }
        return authorityList;
    }

    /**
     * 角色名称集合
     *
     * @return {@link List<String>}
     */
    @JSONField(deserialize = false)
    @ApiModelProperty(value = "角色名称集合", accessMode = READ_ONLY, position = 23)
    public List<String> getRoleNames() {
        if (ArrayUtils.isEmpty(getRoles())) {
            return Collections.emptyList();
        }
        return Stream.of(getRoles())
                .distinct()
                .flatMap(id -> Stream.of(getRoleNameCacheById(id)))
                .collect(Collectors.toList());
    }

    @Override
    public QdslWhere where() {
        final QTabUser table = QTabUser.tabUser;
        return super.where()
                .and(containsAll, () -> table.username.contains(containsAll)
                        .or(table.phone.contains(containsAll))
                        .or(table.nickname.contains(containsAll))
                        .or(table.email.contains(containsAll))
                );
    }

    public static void main(String[] args) {
        final TabUser user = new TabUser();
        user.setUsername("admin");
        user.setPassword("password");
        System.out.println(JSON.toJSONString(TabUserVO.ofTabUser(
                user
        )));
    }
}
